home *** CD-ROM | disk | FTP | other *** search
- /*
- * WTERMF - Window Terminal, 'full' version
- *
- * Matt Kimmel, 1987
- *
- * This program implements a terminal program inside a window as a desk
- * accessory. See the header in the 'stripped' version for programming
- * notes.
- *
- * This version is larger and slower but contains many features - three
- * font sizes, RS232 buffer sizing, a cursor, setting of RS232 parameters,
- * and saving of configuration. This version requires a resource file,
- * WTERMF.C.
- *
- */
- #include <stdio.h>
- #include <gemdefs.h>
- #include <osbind.h>
- #include <obdefs.h>
- #include <string.h>
- #include "wtermf.h" /* Resource defs */
-
- /* Defines for window gadgets */
- #define NAME 0x0001
- #define CLOSE 0x0002
- #define FULL 0x0004
- #define MOVE 0x0008
- #define SIZE 0x0020
- /* Macros to turn mouse pointer on and off */
- #define MOUSE_ON graf_mouse(257,&j)
- #define MOUSE_OFF graf_mouse(256,&j)
-
- /* Structure for iorec() */
- typedef struct {
- char *ibuf;
- int ibufsiz;
- int ibufhd;
- int ibuftl;
- int ibuflow;
- int ibufhi;
- } IORECORD;
-
- /* VDI variables - why aren't these in a header file? */
- int contrl[12], intin[128],ptsin[128],intout[128],ptsout[128];
- int w_handle, handle, workin[11], workout[57];
- int x,y,w,h; /* Current coordinates of window */
- int j;
- int nx, ny; /* coordinates of next character to be output */
- int tx, ty, tw, th; /* Work area of window */
- int hsize, vsize; /* Horizontal and vertical size of characters */
- int apid, menuid;
- OBJECT *mainmenu, *setrs, *setfont, *rsize;
- int baud, ucr, flow, cursor, point, buffer_size; /* Various parameters */
- char *rb; /* Pointer to our RS232 buffer */
- char strsiz[10];
- char aboutstr[] = "[1][Window Term 1.0|Full Version|by Matt Kimmel, 1987][OK]";
-
- main()
- {
- int j;
- int msg[8];
- FILE *conf;
- int dx,dy,dw,dh; /* Desktop work area */
-
- apid = appl_init();
- if (!rsrc_load("WTERMF.RSC"))
- for(;;)
- evnt_mesag(msg); /* If we can't open the resource file, we'll
- just sit here and release the system to
- the time slicer */
- rsrc_gaddr(0,MENU,&mainmenu);
- rsrc_gaddr(0,RS232,&setrs);
- rsrc_gaddr(0,FONT,&setfont);
- rsrc_gaddr(0,BUFSET,&rsize);
- ((TEDINFO *)rsize[BSIZ].ob_spec)->te_ptext = strsiz;
- if ((conf = fopen("\WTERMF.INF","r")) == NULL) {
- /* If we can't open the config file, set up the defaults */
- baud = 7; /* 1200 baud */
- ucr = 136; /* 8,N,1 */
- flow = 0; /* no flow control */
- cursor = 1; /* cursor on */
- point = ((Getrez() == 2)?(10):(9)); /* normal font for this resolution */
- buffer_size = 8192; /* 8K RS232 buffer */
- /* default window coordinates */
- x=50;
- y=50;
- w=200;
- h=100;
- }
- else {
- /* Get parameters from the config file */
- fscanf(conf,"%d",&baud);
- fscanf(conf,"%d",&ucr);
- fscanf(conf,"%d",&flow);
- fscanf(conf,"%d",&cursor);
- fscanf(conf,"%d",&point);
- fscanf(conf,"%d",&buffer_size);
- fscanf(conf,"%d",&x);
- fscanf(conf,"%d",&y);
- fscanf(conf,"%d",&w);
- fscanf(conf,"%d",&h);
- fclose(conf);
- }
- wind_get(0,WF_WORKXYWH,&dx,&dy,&dw,&dh); /* Get work area of desktop */
- /* Fix window coordinates if necessary to fit inside desktop */
- if ((x < dx) || (x > (dx + dw))) x=dx;
- if ((y < dy) || (y > (dy+dh))) y=dy;
- if ((x + w) > (dx + dw)) w=((dx + dw) - x) - 8;
- if ((y + h) > (dy + dh)) h=((dy + dh) - x);
- /* Align window to be byte-aligned in screen RAM */
- align8(&x,&y,&w,&h);
- init_buttons(); /* Set up buttons in dialog boxes */
- if ((point == 10) && (Getrez() != 2)) point = 9; /* Fix font for color */
- Rsconf(baud,flow,ucr,-1,-1,-1);
- menuid = menu_register(apid," Window Terminal");
- handle = graf_handle(&j,&j,&j,&j);
- for(j=0;j++<=9;workin[j]=1);
- workin[10] = 2;
- v_opnvwk(workin,&handle,workout);
- vst_alignment(handle,0,5,&j,&j);
- vst_point(handle,point,&j,&j,&hsize,&vsize);
- vst_color(handle,1);
- vsl_color(handle,1);
- vswr_mode(handle,1);
- /* Allocate new RS232 buffer. calloc() is used because it zeroes the
- memory it allocates */
- rb = calloc(buffer_size,sizeof(char));
- /* If we can't allocate the memory, hang */
- if (rb == NULL)
- for (;;)
- evnt_mesag(msg);
- set_rsbuf();
- for (;;) {
- evnt_mesag(msg); /* Wait around to be selected */
- if (msg[0] == AC_OPEN)
- acc();
- }
- }
-
- /*
- * This is the main accessory - it handles messages and i/o.
- */
- acc()
- {
- int msg[8], d, which;
- int i;
- int a, j;
- int desel = 0; /* Is the window deselected? */
- int dx,dy,dw,dh;
- int stopped = 0; /* Has the window been stopped with ALT-S? */
- long l;
- int p[4];
-
- if (init_window() == 0) return; /*If we can't allocate a window, forget it*/
- align8(&x,&y,&w,&h);
- graf_growbox(24,0,56,16,x,y,w,h);
- wind_open(w_handle,x,y,w,h); /* Open our window */
- wind_get(w_handle,WF_WORKXYWH,&tx,&ty,&tw,&th); /* Get its work area */
- clr(); /* clear it */
- Cauxout(17); /* Send a CTRL-Q, just in case */
- for(;;) {
- /* Release time to the time slicer, but come back every (theoretically)
- 0 milliseconds. Also wait for messages. */
- which = evnt_multi(MU_MESAG|MU_TIMER,0,0,0,0,0,0,0,0,0,0,0,0,0,
- msg,0,0,&d,&d,&d,&d,&d,&d);
- /* See if our window is still on top */
- wind_get(w_handle,WF_TOP,&a,&j,&j,&j);
- if ((a != w_handle) && (desel == 0)) { /* Window has been deselected */
- if (stopped != 1) Cauxout(19); /* Send a CTRL-S if the window isn't
- stopped */
- desel = 1;
- }
- else
- if ((a == w_handle) && (desel == 1)) { /* Window has been selected */
- if (stopped != 1) Cauxout(17); /* Send a CTRL-Q, if window isn't
- stopped */
- desel = 0;
- }
- /* If there are no messages and our window is on top, do some i/o */
- if ((which & MU_TIMER) && (a == w_handle)) {
- /* If there's a character waiting at the keyboard, get it */
- if (Bconstat(2)) {
- l = Bconin(2);
- if (l == 2031616L) /* Is it ALT-S? */
- if (stopped == 0) { /* Yes, toggle stopped window */
- Cauxout(19);
- stopped = 1;
- }
- else {
- Cauxout(17);
- stopped = 0;
- }
- Cauxout((int)l); /* Output the character to RS232. If it was ALT-S,
- a 0 will be output */
- }
- /* If there's a character waiting at the RS232 port, and the
- window is not stopped, output it. */
- if (Cauxis() && (stopped == 0)) {
- i = Cauxin();
- MOUSE_OFF; /* turn off mouse */
- if (cursor) { /* erase cursor */
- p[0] = (nx + (hsize / 2));
- p[1] = (ny - 1);
- p[2] = p[0];
- p[3] = ((ny + vsize) + 1);
- vswr_mode(handle,3);
- v_pline(handle,2,p);
- vswr_mode(handle,1);
- }
- outchar(i); /* output the character */
- if (cursor) { /* draw the cursor */
- p[0] = (nx + (hsize / 2));
- p[1] = (ny - 1);
- p[2] = p[0];
- p[3] = ((ny + vsize) + 1);
- vswr_mode(handle,3);
- v_pline(handle,2,p);
- vswr_mode(handle,1);
- }
- MOUSE_ON; /* turn on the mouse */
- }
- }
- if (which & MU_MESAG) {
- switch(msg[0]) {
- case WM_REDRAW : redraw(); /* redraw window and reset character */
- nx=tx; /* coordinates */
- ny=ty;
- break;
- case WM_NEWTOP : /* put appropriate window on top */
- case WM_TOPPED : wind_set(w_handle,WF_TOP,msg[3],0,0,0);
- clr();
- break;
- case AC_OPEN : do_menu(); /* Let the user select a command */
- break;
- case AC_CLOSE : return; /* Our window has been closed and deleted */
- break; /* for us. */
- case WM_CLOSED : wind_close(w_handle); /* close and delete window */
- graf_shrinkbox(24,0,56,16,x,y,w,h);
- wind_delete(w_handle);
- return; /* exit */
- break;
- case WM_FULLED : full_window();
- break;
- case WM_MOVED : wind_get(0,WF_WORKXYWH,&dx,&dy,&dw,&dh);
- /* Fix window to be inside the desktop */
- if (((msg[4] + msg[6]) - 1) > ((dx + dw) - 1))
- msg[4] = ((dx + dw) - 1) - msg[6];
- if (((msg[5] + msg[7]) - 1) > ((dy + dh) - 1))
- msg[5] = ((dy + dh) - 1) - msg[7];
- align8(&msg[4],&msg[5],&msg[6],&msg[7]);
- nx += (msg[4] - x); /* Cursor will be at the same */
- ny += (msg[5] - y); /* position relative to the */
- x=msg[4]; /* window */
- y=msg[5];
- w=msg[6];
- h=msg[7];
- wind_set(w_handle,WF_CURRXYWH,x,y,w,h);
- wind_get(w_handle,WF_WORKXYWH,&tx,&ty,&tw,&th);
- break;
- case WM_SIZED : x=msg[4]; /* Size window and align it */
- y=msg[5];
- w=msg[6];
- h=msg[7];
- align8(&x,&y,&w,&h);
- wind_set(w_handle,WF_CURRXYWH,x,y,w,h);
- wind_get(w_handle,WF_WORKXYWH,&tx,&ty,&tw,&th);
- clr();
- break;
- }
- continue;
- }
- }
- }
-
- /*
- * this functions fulfills a redraw request. It redraws ALL exposed
- * portions of the window rather than just the 'dirty' rectangles.
- */
- redraw()
- {
- int lx,ly,lw,lh;
- int pxy[4];
- int active;
- int j;
-
- /* if our window is on top, just use the clr() function. It's faster. */
- wind_get(w_handle,WF_TOP,&active,&j,&j,&j);
- if (active == w_handle) {
- clr();
- return;
- }
- vsf_interior(handle,0);
- MOUSE_OFF; /* turn off mouse */
- wind_update(BEG_UPDATE); /* Begin update - don't let GEM change anything */
- /* Get rectangles one by one and fill them in. Fill ALL exposed portions
- of the window. */
- wind_get(w_handle,WF_FIRSTXYWH,&lx,&ly,&lw,&lh);
- while (lw && lh) {
- pxy[0] = lx;
- pxy[1] = ly;
- pxy[2] = (lx + lw) - 1;
- pxy[3] = (ly + lh) - 1;
- vr_recfl(handle,pxy);
- wind_get(w_handle,WF_NEXTXYWH,&lx,&ly,&lw,&lh);
- }
- wind_update(END_UPDATE); /* End our update; let GEM change things again */
- MOUSE_ON; /* turn on mouse */
- }
-
- /*
- * clear the window if it's on top.
- */
- clr()
- {
- int active;
- int j;
- int p[4];
-
- /* Don't do anything if our window is not on top. */
- wind_get(w_handle,WF_TOP,&active,&j,&j,&j);
- if (active == w_handle) {
- wind_get(w_handle,WF_WORKXYWH,&p[0],&p[1],&p[2],&p[3]); /* get work area */
- p[2] += (p[0] - 1); /* Fix w and h to be x2 and y2 */
- p[3] += (p[1] - 1);
- vsf_interior(handle,0);
- MOUSE_OFF;
- vr_recfl(handle,p); /* Wipe window */
- nx=tx; /* Reset character coordinates */
- ny=ty;
- /* Draw the cursor if necessary */
- if (cursor) {
- p[0] = (nx + (hsize / 2));
- p[1] = (ny - 1);
- p[2] = p[0];
- p[3] = ((ny + vsize) + 1);
- vswr_mode(handle,1);
- v_pline(handle,2,p);
- }
- MOUSE_ON;
- }
- }
-
- /*
- * Make sure that the window's work area is byte-aligned. this speeds
- * up scrolling with vro_cpyfm().
- */
- align8(fx,fy,fw,fh)
- int *fx,*fy,*fw,*fh;
- {
- int ix,iy,iw,ih;
-
- /* This returns coordinates for the entire window, not just the work
- area, so we need to convert coordinates back and forth with
- wind_calc(). */
- wind_calc(1,NAME|CLOSE|FULL|MOVE|SIZE,*fx,*fy,*fw,*fh,&ix,&iy,&iw,&ih);
- while ((ix % 8) != 0)
- ix++;
- while ((iw % 8) != 0)
- iw++;
- wind_calc(0,NAME|CLOSE|FULL|MOVE|SIZE,ix,iy,iw,ih,fx,fy,fw,fh);
- }
-
- /*
- * fulfill a full_window() request.
- */
- full_window()
- {
- int jx,jy,jw,jh,fx,fy,fw,fh;
-
- /* get 'full size'. This is already byte-aligned. */
- wind_get(w_handle,WF_FULLXYWH,&fx,&fy,&fw,&fh);
- /* if the window is already full, unfull it. */
- if ((x == fx) && (y == fy) && (w == fw) && (h == fh)) {
- wind_get(w_handle,WF_PREVXYWH,&jx,&jy,&jw,&jh);
- graf_shrinkbox(jx,jy,jw,jh,x,y,w,h);
- x=jx;
- y=jy;
- w=jw;
- h=jh;
- wind_set(w_handle,WF_CURRXYWH,x,y,w,h);
- wind_get(w_handle,WF_WORKXYWH,&tx,&ty,&tw,&th);
- nx=tx;
- ny=ty;
- }
- else { /* full the window */
- wind_get(w_handle,WF_FULLXYWH,&jx,&jy,&jw,&jh);
- graf_growbox(x,y,w,h,jx,jy,jw,jh);
- x=jx;
- y=jy;
- w=jw;
- h=jh;
- wind_set(w_handle,WF_CURRXYWH,x,y,w,h);
- wind_get(w_handle,WF_WORKXYWH,&tx,&ty,&tw,&th);
- nx=tx;
- ny=ty;
- }
- clr();
- }
-
- /*
- * initialize and allocate the window
- */
- init_window()
- {
- int bx,by,bw,bh;
-
- wind_get(0,WF_WORKXYWH,&bx,&by,&bw,&bh); /* set up FULLXYWH value */
- align8(&bx,&by,&bw,&bh);
- bw -= 8;
- w_handle = wind_create(NAME|CLOSE|FULL|MOVE|SIZE,bx,by,bw,bh);
- if (w_handle < 0) { /* If we can't allocate a window, apologize */
- form_alert(1,"[3][There are no more|windows available!][Sorry!]");
- return (0);
- }
- wind_set(w_handle,WF_NAME," Window Term 1.0-F ",0,0);
- return(1);
- }
-
- /*
- * Install our new RS232 buffer
- */
- set_rsbuf()
- {
- IORECORD *b;
-
- Cauxout(19); /* We don't want incoming characters during this */
- b = (IORECORD *)Iorec(0); /* make our structure point to the RS232 struct */
- b->ibuf = rb; /* fill it in! */
- b->ibufsiz = buffer_size;
- b->ibuflow = buffer_size/4;
- b->ibufhi = buffer_size/4*3;
- b->ibufhd = 0;
- b->ibuftl = 0;
- Cauxout(17); /* Send a CTRL-Q */
- }
-
- /*
- * Set up the buttons on the dialog boxes
- */
- init_buttons()
- {
- int j;
- char foo[10];
-
- /* Clear all the buttons */
- for (j=0;j<=32;j++)
- if (((setrs[j].ob_type) == G_BUTTON)||((setrs[j].ob_type) == G_BOXCHAR)) {
- setrs[j].ob_state &= (~SELECTED);
- setrs[j].ob_state |= NORMAL;
- }
- for (j=0;j<=7;j++)
- if ((setfont[j].ob_type) == G_BUTTON) {
- setfont[j].ob_state &= (~SELECTED);
- setfont[j].ob_state |= NORMAL;
- }
- /* Set appropriate buttons */
- if (baud == 0) objc_change(setrs,B19200,0,0,0,0,0,SELECTED,0);
- if (baud == 1) objc_change(setrs,B9600,0,0,0,0,0,SELECTED,0);
- if (baud == 2) objc_change(setrs,B4800,0,0,0,0,0,SELECTED,0);
- if (baud == 4) objc_change(setrs,B2400,0,0,0,0,0,SELECTED,0);
- if (baud == 7) objc_change(setrs,B1200,0,0,0,0,0,SELECTED,0);
- if (baud == 9) objc_change(setrs,B300,0,0,0,0,0,SELECTED,0);
- if (flow == 0) objc_change(setrs,FLOWNONE,0,0,0,0,0,SELECTED,0);
- if (flow == 1) objc_change(setrs,FLOWXON,0,0,0,0,0,SELECTED,0);
- if (flow == 2) objc_change(setrs,FLOWRTS,0,0,0,0,0,SELECTED,0);
- if (flow == 3) objc_change(setrs,FLOWBOTH,0,0,0,0,0,SELECTED,0);
- if ((ucr & 4) && (ucr & 2))
- objc_change(setrs,EVEN,0,0,0,0,0,SELECTED,0);
- if ((ucr & 4) && (!(ucr & 2)))
- objc_change(setrs,ODD,0,0,0,0,0,SELECTED,0);
- if (!(ucr & 4))
- objc_change(setrs,NONE,0,0,0,0,0,SELECTED,0);
- if ((!(ucr & 16)) && (ucr & 8))
- objc_change(setrs,STOP1,0,0,0,0,0,SELECTED,0);
- if ((ucr & 16) && (ucr & 8))
- objc_change(setrs,STOP2,0,0,0,0,0,SELECTED,0);
- if ((!(ucr & 64)) && (!(ucr & 32)))
- objc_change(setrs,BIT8,0,0,0,0,0,SELECTED,0);
- if ((!(ucr & 64)) && (ucr & 32))
- objc_change(setrs,BIT7,0,0,0,0,0,SELECTED,0);
- if ((ucr & 64) && (!(ucr & 32)))
- objc_change(setrs,BIT6,0,0,0,0,0,SELECTED,0);
- if ((ucr & 64) && (ucr & 32))
- objc_change(setrs,BIT5,0,0,0,0,0,SELECTED,0);
- if ((point == 10) && (Getrez() != 2))
- objc_change(setfont,COLOR,0,0,0,0,0,SELECTED,0);
- else
- if (point == 10)
- objc_change(setfont,MONO,0,0,0,0,0,SELECTED,0);
- if (point == 9)
- objc_change(setfont,COLOR,0,0,0,0,0,SELECTED,0);
- if (point == 8)
- objc_change(setfont,ICON,0,0,0,0,0,SELECTED,0);
- if (Getrez() != 2)
- objc_change(setfont,MONO,0,0,0,0,0,DISABLED,0);
- sprintf(strsiz,"%d",buffer_size);
- }
-
- /*
- * Do main dialog; allow user to select a command
- */
- do_menu()
- {
- int which;
- int dx,dy,dw,dh;
-
- evnt_timer(0,0); /* Lots of stuff to make sure dialogs aren't */
- wind_update(BEG_UPDATE); /* redrawn over by other applications */
- form_center(mainmenu,&dx,&dy,&dw,&dh);
- form_dial(FMD_START,dx,dy,dw,dh,dx,dy,dw,dh);
- objc_draw(mainmenu,0,10,dx,dy,dw,dh);
- which = form_do(mainmenu,0);
- objc_change(mainmenu,which,0,0,0,0,0,NORMAL,0);
- wind_update(END_UPDATE);
- form_dial(FMD_FINISH,dx,dy,dw,dh,dx,dy,dw,dh);
- switch(which) {
- case SETRS232 : set_rs232();
- break;
- case BUFSIZE : size_buffer();
- break;
- case SETSIZE : set_charsize();
- break;
- case CURSON : cursor = ((cursor == 1)?(0):(1));
- clr();
- break;
- case SAVESET : save_settings();
- break;
- case ABOUT : form_alert(1,aboutstr);
- break;
- }
- }
-
- /*
- * Let user set RS232 parameters
- */
- set_rs232()
- {
- int which;
- int dx,dy,dw,dh;
-
- /* Do the dialog ... */
- evnt_timer(0,0);
- wind_update(BEG_UPDATE);
- form_center(setrs,&dx,&dy,&dw,&dh);
- form_dial(FMD_START,dx,dy,dw,dh,dx,dy,dw,dh);
- objc_draw(setrs,0,10,dx,dy,dw,dh);
- which = form_do(setrs,0);
- objc_change(setrs,which,0,0,0,0,0,NORMAL,0);
- wind_update(END_UPDATE);
- form_dial(FMD_FINISH,dx,dy,dw,dh,dx,dy,dw,dh);
- if (which == RCANCEL) {
- init_buttons();
- return;
- }
- /* ... and set the parameters accordingly */
- if (sel(setrs,B19200)) baud = 0;
- if (sel(setrs,B9600)) baud = 1;
- if (sel(setrs,B4800)) baud = 2;
- if (sel(setrs,B2400)) baud = 4;
- if (sel(setrs,B1200)) baud = 7;
- if (sel(setrs,B300)) baud = 9;
- if (sel(setrs,FLOWNONE)) flow = 0;
- if (sel(setrs,FLOWXON)) flow = 1;
- if (sel(setrs,FLOWRTS)) flow = 2;
- if (sel(setrs,FLOWBOTH)) flow = 3;
- ucr = 0;
- if (sel(setrs,EVEN)) ucr |= 6;
- if (sel(setrs,ODD)) ucr |= 4;
- if (sel(setrs,STOP1)) ucr |= 8;
- if (sel(setrs,STOP2)) ucr |= 24;
- if (sel(setrs,BIT7)) ucr |= 32;
- if (sel(setrs,BIT6)) ucr |= 64;
- if (sel(setrs,BIT5)) ucr |= 96;
- ucr |= 128;
- Rsconf(baud,flow,ucr,-1,-1,-1);
- }
-
- /*
- * Let the user size the RS232 buffer
- */
- size_buffer()
- {
- int dx,dy,dw,dh,which;
- int oldbuf;
-
- /* Do the dialog */
- evnt_timer(0,0);
- wind_update(BEG_UPDATE);
- form_center(rsize,&dx,&dy,&dw,&dh);
- form_dial(FMD_START,dx,dy,dw,dh,dx,dy,dw,dh);
- objc_draw(rsize,0,10,dx,dy,dw,dh);
- which = form_do(rsize,BSIZ);
- objc_change(rsize,which,0,0,0,0,0,NORMAL,0);
- wind_update(END_UPDATE);
- form_dial(FMD_FINISH,dx,dy,dw,dh,dx,dy,dw,dh);
- if (which == BCANCEL) {
- init_buttons();
- return;
- }
- /* set size */
- oldbuf = buffer_size; /* save old buffer size */
- buffer_size = atoi(strsiz); /* get new one */
- free(rb); /* free the old memory */
- rb = calloc(buffer_size,sizeof(char)); /* allocate the new */
- if (rb == NULL) { /* if bad, generally bomb out. */
- form_alert(1,"[3][Not enough memory|for a buffer of|that size.][Cancel]");
- buffer_size = oldbuf;
- rb = calloc(buffer_size,sizeof(char)); /* reallocate the old buffer. We
- don't have any error-checking
- here because if this fails,
- we're in big trouble anyway */
- init_buttons();
- return;
- }
- set_rsbuf();
- }
-
- /*
- * Let user set the font (Mono, color, icon)
- */
- set_charsize()
- {
- int dx,dy,dw,dh,which,j;
-
- evnt_timer(0,0);
- wind_update(BEG_UPDATE);
- form_center(setfont,&dx,&dy,&dw,&dh);
- form_dial(FMD_START,dx,dy,dw,dh,dx,dy,dw,dh);
- objc_draw(setfont,0,10,dx,dy,dw,dh);
- which = form_do(setfont,0);
- objc_change(setfont,which,0,0,0,0,0,NORMAL,0);
- wind_update(END_UPDATE);
- form_dial(FMD_FINISH,dx,dy,dw,dh,dx,dy,dw,dh);
- if (which == FCANCEL) {
- init_buttons();
- return;
- }
- if (sel(setfont,MONO)) point = 10;
- if (sel(setfont,COLOR)) point = 9;
- if (sel(setfont,ICON)) point = 8;
- vst_point(handle,point,&j,&j,&hsize,&vsize);
- clr();
- }
-
- /*
- * save the configuration
- */
- save_settings()
- {
- int j;
- FILE *fd;
-
- if ((fd = fopen("\WTERMF.INF","w")) == NULL) {
- form_alert(1,"[3][Couldn't open|\WTERMF.INF\for writing.][Cancel]");
- return;
- }
- graf_mouse(2,&j); /* "busy as a bee " */
- fprintf(fd,"%d\n",baud);
- fprintf(fd,"%d\n",ucr);
- fprintf(fd,"%d\n",flow);
- fprintf(fd,"%d\n",cursor);
- fprintf(fd,"%d\n",point);
- fprintf(fd,"%d\n",buffer_size);
- fprintf(fd,"%d\n%d\n%d\n%d\n",x,y,w,h);
- fclose(fd);
- graf_mouse(0,&j);
- }
-
- /*
- * Return non-zero if obj in tree is selected
- */
- sel(tree,obj)
- OBJECT *tree;
- int obj;
- {
- if ((tree[obj].ob_state) & SELECTED)
- return (1);
- else
- return (0);
- }
-
- /*
- * output a character to the window, and scroll if necessary.
- * Why doesn't the ST have built-in scrolling and such for its
- * windows?
- */
- outchar(ch)
- int ch;
- {
- char str[2];
- int j;
-
- if (ch == 10) { /* Linefeed */
- if ((ny + vsize) > ((ty + th) - vsize)) { /* scroll if necessary */
- scroll();
- return;
- }
- ny += vsize;
- return;
- }
- if (ch == 13) { /* Carriage Return */
- nx = tx;
- return;
- }
- if (ch == 7) { /* Bell */
- Bconout(2,7); /* ding! */
- return;
- }
- if ((ch == 8) && (cursor)) { /* cursor is non-destructive if the cursor */
- if (nx > tx) /* is on. */
- nx -= hsize;
- return;
- }
- if (ch == 9) { /* Tab */
- outchar(32); /* faster than a for loop */
- outchar(32);
- outchar(32);
- outchar(32);
- outchar(32);
- /* Tabs are 5 characters right now. Perhaps in a later version I'll
- let the user set the tab size. */
- return;
- }
- if (ch == 12) { /* Form Feed (clear screen) */
- clr();
- nx=tx;
- ny=ty;
- return;
- }
- if ((ch == 127) || ((ch == 8) && (!cursor))) { /* DEL and Backspace */
- if (nx > tx) {
- nx -= hsize;
- v_gtext(handle,nx,ny," ");
- }
- return;
- }
- str[0] = (char)ch;
- str[1] = '\0';
- v_gtext(handle,nx,ny,str); /* output the character */
- nx += hsize;
- if (nx > ((tx + tw) - hsize)) { /* wrap if necessary */
- nx = tx;
- if ((ny + vsize) > ((ty + th) - vsize)) scroll(); /* scroll if necessary */
- else ny += vsize;
- }
- }
-
- /*
- * This routine scrolls the window up one line. This should be built into
- * the ST - it took me quite a while to get this thing working.
- * Basically what it does is copy all the lines but the top one up one
- * line (as one block). Then it wipes the bottom line clean.
- */
- scroll()
- {
- int pxy[4];
-
- blit(tx,(ty + vsize),((tx + tw) - 1),(((ty + vsize) + th) - (vsize + 1)),
- tx,ty,((tx + tw) - 1),((ty + th) - (vsize + 1)));
- pxy[0] = tx;
- pxy[1] = ny;
- pxy[2] = (tx + tw) - 1;
- pxy[3] = ny + vsize;
- vsf_interior(handle,0);
- vr_recfl(handle,pxy);
- }
-
- /*
- * copy the block defined by x1, y1, x2, y2 to x3, y3, x4, y4
- */
- blit(x1,y1,x2,y2,x3,y3,x4,y4)
- int x1,y1,x2,y2,x3,y3,x4,y4;
- {
- FDB b;
- int bp[8];
-
- bp[0] = x1;
- bp[1] = y1;
- bp[2] = x2;
- bp[3] = y2;
- bp[4] = x3;
- bp[5] = y3;
- bp[6] = x4;
- bp[7] = y4;
- vro_cpyfm(handle,3,bp,&b,&b); /* zap! */
- }
-